O                       [0-7]
D                       [0-9]
L                       [a-zA-Z_]
H                       [a-fA-F0-9]
E                       [Ee][+-]?{D}+
FS                      (f|F|l|L)
IS                      (u|U|l|L)
W                       [ \t\f]*
LIT         \"(\\.|[^\\"])*\"

%{
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
//#include "lexer.h"
#include "ssigram.tab.h"
#include "token.h"
#include "tree.h"

//externs and definitions----------------------------------------------
extern int linenum;
extern int yywrap();
char *fname;

%}

%%

<<EOF>>			{ return -1;}
\n			{ linenum++;}
[ \t\f]+		{ /*do nothing*/}

"with\nparameter"	{ CreateToken(WITHPARAMETER, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return WITHPARAMETER;}

"create view"		{ CreateToken(CREATEVIEW, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return CREATEVIEW;}

"extract"		{ CreateToken(EXTRACT, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return EXTRACT;}

"select"		{ CreateToken(SELECT, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return SELECT;}

"from"			{ CreateToken(FROM, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return FROM;}

"where"			{ CreateToken(WHERE, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return WHERE;}

"as"			{ CreateToken(AS, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return AS;}

"using"			{ CreateToken(USING, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return USING;}

"distinct"		{ CreateToken(DISTINCT, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return DISTINCT;}

"."			{ CreateToken(PERIOD, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return PERIOD;}

"("			{ CreateToken(LP, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return LP;}

")"			{ CreateToken(RP, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return RP;}

"'"			{ CreateToken(APOSTRAPHE, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return APOSTRAPHE;}

"="			{ CreateToken(EQ, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return EQ;}

"<="			{ CreateToken(LTEQ, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return LTEQ;}

">="			{ CreateToken(GTEQ, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return GTEQ;}

"<"			{ CreateToken(LT, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return LT;}

">"			{ CreateToken(GT, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return GT;}

"not"			{ CreateToken(NOT, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return NOT;}

"in"			{ CreateToken(IN, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return IN;}

"natural join"		{ CreateToken(NJ, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return NJ;}

"max"			{ CreateToken(MAX, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return MAX;}

"min"			{ CreateToken(MIN, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return MIN;}

"avg"			{ CreateToken(AVG, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return AVG;}

"count"			{ CreateToken(COUNT, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return COUNT;}

"exists"		{ CreateToken(EXISTS, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return EXISTS;}

"and"			{ CreateToken(AND, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return AND;}

{D}+{IS}?		{ CreateToken(ICON, yytext, linenum, fname, 1);
				yylval.n = createnode(yytext, DupToken(), 0);
				return ICON;}




{L}({L}|{D})*		{ CreateToken(IDENT, yytext, linenum, fname, 1);
				yylval.n = createnode(yytext, DupToken(), 0);
				return IDENT; }

{LIT}			{ CreateToken(STRING, yytext, linenum, fname, 1);
				yylval.n = createnode(yytext, DupToken(), 0);
				return STRING;}

","			{ CreateToken(COMMA, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return COMMA;}

"/"			{ CreateToken(SLASH, yytext, linenum, fname, 0);
				yylval.n = createnode(yytext, DupToken(), 0);
				return SLASH;}

[^ \t\n]		{ yyerror("Lex error");}


%%

//helper function section
int yyerror(char *s)
{
	int errorreturntype = 0;
//	errors++;


	fprintf(stderr, "%s: ", s);

	if(fname)
		fprintf(stderr, "file \"%s\", ", fname );

	fprintf(stderr, "line %d, token = \"%s\"\n",
                                  linenum, yytext);
	if(s[0] == 'l' && s[1] == 'e' && s[2] == 'x')
	{
		errorreturntype = 1;   //lex error
		exit(errorreturntype);
	}
	else if(s[0] == 's' && s[1] == 'y' && s[2] == 'n')
	{
		errorreturntype = 2;   //syntax error
		exit(errorreturntype);
	}
	else
	{
		errorreturntype = 3;   //WTF error?
		exit(errorreturntype);
	}
//	errorreturntype = -2;

}

int yywrap()
{
	fclose(yyin);
	return 1;
}
